package com.laviedesfons.jhmtasc.metadata;

import com.laviedesfons.jhmtasc.exceptions.MException;
import com.laviedesfons.jhmtasc.types.abstracts.AbstractType;
import com.laviedesfons.jhmtasc.types.interfaces.InternalType;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Romano
 */
public class MetaModel extends MetaType {

    private String flag = "";
    private Map<Integer,MetaField> valueFields = new HashMap<Integer,MetaField>() ;
    private Map<Integer, MetaField> offsetFields = new HashMap<Integer,MetaField>();
    private boolean isRootType = false;
    private MetaField parentField;
    private MetaModel parent;

    public MetaModel(Class<? extends InternalType> cl) {
        super(cl);
        setIsPrimitive(false);
    }

    MetaModel(String c) {
        super(c);
        setIsPrimitive(false);
    }

    // TODO use generics..
    @Override
    public Class<? extends AbstractType> getClazz() {
        return (Class<? extends AbstractType>) super.getClazz();
    }

    public final int getFieldsLength(){
        return valueFields.size() + offsetFields.size();
    }

    public final MetaField getValueField(int id) throws MException{
        MetaField f;
        if((f = valueFields.get(Integer.valueOf(id))) != null){
            return f;
        }
        throw new MException("unknown id("+id+") in "+getName());
    }

    public final MetaField getOffsetField(int id) throws MException{
        MetaField f;
        if((f = offsetFields.get(Integer.valueOf(id))) != null){
            return f;
        }
        throw new MException("unknown id("+id+") in "+getName());
    }

    public final boolean isRootType(){
        return isRootType;
    }

    public final String getFlag() {
        return flag;
    }

    public final Collection<MetaField> getOffsetFields(){
       return offsetFields.values();
    }

    public final Collection<MetaField> getValueFields(){
       return valueFields.values();
    }

    public final MetaField getParentField() {
        return parentField;
    }

    public final MetaModel getParent() {
        return parent;
    }

    final void setParentField(MetaField parentField) {
        this.parentField = parentField;
    }

    void setIsRootType(boolean b){
        isRootType = b;
    }

    final void setFlag(String flag) {
        this.flag = flag;
    }

    final void addValueField(MetaField f) {
        valueFields.put(Integer.valueOf(f.getId()),f);
    }

    final void addOffsetField(MetaField f) {
        offsetFields.put(Integer.valueOf(f.getId()),f);
    }

    final void setParent(MetaModel p) {
        parent = p;
    }

    @Override
    public String toString() {
        return String.format("%s{flag=%s, parent=%s, isRootType=%s, %s}",
                MetaModel.class.getSimpleName(),
                flag,
                isRootType() ? "true" : "false",
                (parent == null ? "null" : parent.getName()),
                super.toString());
    }
}
